package tom.spring.cloud.feign.controller;

import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import tom.spring.cloud.api.vo.HelloParam;
import tom.spring.cloud.feign.service.HelloApiService;

/**
 * 接口uri定义不能和HelloApiService中的uri相同
 * @author ZHUFEIFEI
 */
@RestController
@RequestMapping("feign/api")
public class HelloApiController {

    @Autowired
    private HelloApiService apiService;

    @HystrixCommand(fallbackMethod = "unavailable")
    @GetMapping("hello")
    public String hello() {
        return this.apiService.hello();
    }

    /**
     * 为了测试feign-ribbon重试机制，hystrix超时时间要大于ribbon的readTimeout时间
     * provider01启动两个以上。
     * 访问可以看到大部分是成功的，这是重试机制的效果。
     * 到provider01的控制台可以看到当随机睡眠超过1秒时会收到第二次请求
     * @return
     */
    @HystrixCommand(commandProperties = {
            @HystrixProperty(name="execution.timeout.enabled", value="true"),
            @HystrixProperty(name="execution.isolation.thread.timeoutInMilliseconds", value = "5000")
    }, fallbackMethod = "unavailable")
    @GetMapping("timeout")
    public String timeout() {
        return this.apiService.timeout();
    }

    /**
     * open-feign 支持通过get请求传递对象类型的参数
     * @return
     */
    @HystrixCommand(commandProperties = {
            @HystrixProperty(name="execution.timeout.enabled", value="true"),
            @HystrixProperty(name="execution.isolation.thread.timeoutInMilliseconds", value = "5000")
    }, fallbackMethod = "unavailable")
    @GetMapping("query/map")
    public String queryMap() {
        HelloParam param = new HelloParam();
        param.setHello("hello !");
        param.setTime(System.currentTimeMillis());
        return this.apiService.queryMap(param);
    }

    public String unavailable() {
        return "service unavailable!";
    }
}
